#ifndef TRACKER_CONFIG_H
#define TRACKER_CONFIG_H

#include <muduo/base/Types.h>
#include <muduo/base/Logging.h>
#include <fstream>
#include <assert.h>
#include <pthread.h>

#include <boost/noncopyable.hpp>

#include <sdfs/config/Json.h>
#include <sdfs/common/ToolKit.h>

using namespace muduo;

namespace sdfs
{
class TrackerConfig: public boost::noncopyable
{
public:

	typedef boost::shared_ptr<TrackerConfig> TrackerConfigPtr;

	static TrackerConfig& getInstance()
	{
		pthread_once(&ponce_, &TrackerConfig::parseConfg);
		return *instance_;
	}

	static void setConfigFilename(const muduo::string &filename)
	{
		assert(sdfs::ToolKit::getCfgFileName(confname_, filename) == true);
	}
	
	~TrackerConfig(){}
private:

	TrackerConfig()
	{
	}

	static void parseConfg()
	{
		assert(confname_.length() != 0);
		instance_ = new TrackerConfig();
		sdfs::JsonValuePtr tree = sdfs::JsonHelper::ParseJson(confname_);
		assert(tree != NULL);
		instance_->name_ = (*tree)["name"].asString().c_str();
		instance_->port_ = (*tree)["port"].asInt();
		instance_->storagePort_ = (*tree)["storagePort"].asInt();
		instance_->confPort_ = (*tree)["configPort"].asInt();
		instance_->heartBeatIntervalMs_ = (*tree)["heartBeatIntervalMs"].asInt();
		instance_->heartBeatTimeoutMs_ = (*tree)["heartBeatTimeoutMs"].asInt();
		instance_->threadNum_ = (*tree)["threadNum"].asInt();
		instance_->syncIntervalS_ = (*tree)["syncIntervalS"].asInt();
		Json::Value redisRoot = (*tree)["redis"];
		instance_->redisIp_ = redisRoot["ip"].asString().c_str();
		instance_->redisPort_ = redisRoot["port"].asInt();
		
		LOG_INFO << "server config: [" << name() << ":" << port() <<
			" sport:" << storagePort() << " confPort: " << confPort() <<
			" heartbeat: "<< heartBeatIntervalMs()<<" "<< heartBeatTimeoutMs() <<
			" threadNum: " << threadNum();
		
	}
public:

	static int port()
	{
		return instance_->port_;
	}

	static int storagePort()
	{
		return instance_->storagePort_;
	}

	static int confPort()
	{
		return instance_->confPort_;
	}

	static int heartBeatIntervalMs()
	{
		return instance_->heartBeatIntervalMs_;
	}

	static int heartBeatTimeoutMs()
	{
		return instance_->heartBeatTimeoutMs_;
	}

	static int threadNum()
	{
		return instance_->threadNum_;
	}

	static muduo::string& name()
	{
		return instance_->name_;
	}

	static muduo::string& redisIp()
	{
		return instance_->redisIp_;
	}

	static int redisPort()
	{
		return instance_->redisPort_;
	}

	static int syncIntervalS()
	{
		return instance_->syncIntervalS_;
	}
private:
	muduo::string name_;
	int port_;
	int storagePort_;
	int confPort_;
	int heartBeatIntervalMs_;
	int heartBeatTimeoutMs_;
	int threadNum_;
	muduo::string redisIp_;
	int redisPort_;
	int syncIntervalS_;


	static muduo::string confname_;

	static TrackerConfig* instance_;
	static pthread_once_t ponce_;

};

pthread_once_t TrackerConfig::ponce_ = PTHREAD_ONCE_INIT;
TrackerConfig* TrackerConfig::instance_ = NULL;
muduo::string TrackerConfig::confname_ = "";

}

#endif